package com.jstyle.jclifexd.utils;

import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;
import android.util.Log;

import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.fitness.Fitness;
import com.google.android.gms.fitness.data.DataPoint;
import com.google.android.gms.fitness.data.DataSet;
import com.google.android.gms.fitness.data.DataSource;
import com.google.android.gms.fitness.data.DataType;
import com.google.android.gms.fitness.data.Field;
import com.google.android.gms.tasks.OnCanceledListener;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.Task;

import com.jstyle.jclifexd.BuildConfig;
import com.jstyle.jclifexd.NetWork.NetWorkUtil;
import com.jstyle.jclifexd.R;
import com.jstyle.jclifexd.app.MyApplication;
import com.jstyle.jclifexd.daoManager.HeartDataDaoManager;
import com.jstyle.jclifexd.daoManager.PathRecordDaoManager;
import com.jstyle.jclifexd.daoManager.StepDataDaoManager;
import com.jstyle.jclifexd.daoManager.StepDetailDataDaoManager;
import com.jstyle.jclifexd.model.HeartData;
import com.jstyle.jclifexd.model.NetResultData;
import com.jstyle.jclifexd.model.PathRecord;
import com.jstyle.jclifexd.model.PathRecorderror;
import com.jstyle.jclifexd.model.StepData;
import com.jstyle.jclifexd.model.StepDataerror;
import com.jstyle.jclifexd.model.StepDetailData;
import com.jstyle.jclifexd.model.UploadData;
import com.jstyle.jclifexd.model.UploadGpsData;
import com.jstyle.jclifexd.model.UploadGpsDataError;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.logging.SimpleFormatter;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

public class UploadUtils {
    private static final String TAG = "UploadUtils";

    public static void uploadData(UploadData uploadData) {
        if(!NetWorkUtil.isNetworkConnected(MyApplication.instance()))return;
        NetWorkUtil.getInstance().getJstyleApi()
                .uploadData(uploadData).compose(SchedulersTransformer.<NetResultData>io2MainObservable()).subscribe(new Observer<NetResultData>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(NetResultData netResultData) {
            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "onError: " + e.getLocalizedMessage());
            }

            @Override
            public void onComplete() {

            }
        });
    }

    public static void uploadDatapath(UploadData uploadData,final List<PathRecord> pathRecordList,final int type) {
        NetWorkUtil.getInstance().getJstyleApi()
                .uploadData(uploadData).compose(SchedulersTransformer.<NetResultData>io2MainObservable()).subscribe(new Observer<NetResultData>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(NetResultData netResultData) {
                if(0==type){
                    if(netResultData.getMsgCode()!=1){
                        List<PathRecorderror>  Plist=new ArrayList<>();
                        for (int i=0;i<pathRecordList.size();i++){
                            PathRecorderror pp=new PathRecorderror();
                            pp.setMDate(pathRecordList.get(i).getMDate());
                            pp.setExerciseMode(pathRecordList.get(i).getExerciseMode());
                            pp.setCalString(pathRecordList.get(i).getCalString());
                            pp.setMDistance(pathRecordList.get(i).getMDistance());
                            pp.setMAveragespeed(pathRecordList.get(i).getMAveragespeed());
                            pp.setHeart(pathRecordList.get(i).getHeart());
                            pp.setMStep(pathRecordList.get(i).getMStep());
                            pp.setMDuration(pathRecordList.get(i).getMDuration());
                            pp.setAddress(pathRecordList.get(i).getAddress());
                            Plist.add(pp);
                        }
                        PathRecordDaoManager.insertPathError(Plist);
                    }else{
                        Log.i(TAG, "onsucess: " + "111111111"+netResultData.toString());
                        if(1==type){
                            PathRecordDaoManager.deleteAllError();
                        }

                    }
                }

            }

            @Override
            public void onError(Throwable e) {
                if(0==type){
                    List<PathRecorderror>  Plist=new ArrayList<>();
                    for (int i=0;i<pathRecordList.size();i++){
                        PathRecorderror pp=new PathRecorderror();
                        pp.setMDate(pathRecordList.get(i).getMDate());
                        pp.setExerciseMode(pathRecordList.get(i).getExerciseMode());
                        pp.setCalString(pathRecordList.get(i).getCalString());
                        pp.setMDistance(pathRecordList.get(i).getMDistance());
                        pp.setMAveragespeed(pathRecordList.get(i).getMAveragespeed());
                        pp.setHeart(pathRecordList.get(i).getHeart());
                        pp.setMStep(pathRecordList.get(i).getMStep());
                        pp.setMDuration(pathRecordList.get(i).getMDuration());
                        pp.setAddress(pathRecordList.get(i).getAddress());
                        Plist.add(pp);
                    }
                    PathRecordDaoManager.insertPathError(Plist);
                    Log.i(TAG, "Error: " + "2222222222"+e.toString());
                }
            }

            @Override
            public void onComplete() {

            }
        });
    }
    public static void uploadData(UploadData uploadData,final List<StepData> stepDataList,final int type) {
        if(!NetWorkUtil.isNetworkConnected(MyApplication.instance()))return;
        NetWorkUtil.getInstance().getJstyleApi()
                .uploadData(uploadData).compose(SchedulersTransformer.<NetResultData>io2MainObservable()).subscribe(new Observer<NetResultData>() {
            @Override
            public void onSubscribe(Disposable d) {
            }
            @Override
            public void onNext(NetResultData netResultData) {
                Log.i(TAG, "onsucess: " + "22222222222222"+netResultData.toString());
                if(!netResultData.getMsgInfo().equals("成功")){
                    insertError(stepDataList);
                }else{
                    if(1==type){
                        StepDataDaoManager.deleteErroe();
                        Log.i("sdsds", "已删除数据" );
                    }
                }
            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "onError: " + e.getLocalizedMessage());
                insertError(stepDataList);
            }

            @Override
            public void onComplete() {

            }
        });
    }

    private static void insertError(List<StepData> stepDataList){
        List<StepDataerror> stepDataListb=new ArrayList<>();
        stepDataListb.clear();
        for (int i=0;i<stepDataList.size();i++){
            StepDataerror ss=new StepDataerror();
            ss.setAddress(stepDataList.get(i).getAddress());
            ss.setCal(stepDataList.get(i).getCal());
            ss.setDate(stepDataList.get(i).getDate());
            ss.setDistance(stepDataList.get(i).getDistance());
            ss.setExerciseTime(stepDataList.get(i).getExerciseTime());
            ss.setShowLabel(stepDataList.get(i).getShowLabel());
            ss.setStep(stepDataList.get(i).getStep());
            ss.setGoal(stepDataList.get(i).getGoal());
            stepDataListb.add(ss);
        }
        StepDataDaoManager.inserterrorData(stepDataListb);
    }


    public static void uploadOtaLogData(Context context,String deviceType,String fwVersion,String content) {
        Map<String, String> logMap = new HashMap<>();
        String uid=NetWorkUtil.getUserId();
        String appName=context.getString(R.string.app_name);
        String appVersion= BuildConfig.VERSION_NAME;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date=format.format(new Date());
        logMap.put(NetWorkConast.KEY_uid,uid);
        logMap.put(NetWorkConast.KEY_exType,"Ota");
        logMap.put(NetWorkConast.KEY_AppName,appName);
        logMap.put(NetWorkConast.KEY_AppVersion,appVersion);
        logMap.put(NetWorkConast.KEY_devicetype,deviceType);
        logMap.put(NetWorkConast.KEY_osType,"Android "+ Build.VERSION.SDK_INT);
        logMap.put(NetWorkConast.KEY_LOGContent,content);
        logMap.put(NetWorkConast.KEY_FimwareVersion,fwVersion);
        logMap.put(NetWorkConast.KEY_LOGDate,date);
        NetWorkUtil.getInstance().getJstyleApi()
                .uploadOtaLog(logMap).compose(SchedulersTransformer.<NetResultData>io2MainObservable()).subscribe(new Observer<NetResultData>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(NetResultData netResultData) {
                Log.i(TAG, "onNext: ");
            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "onError: " + e.getLocalizedMessage());
            }

            @Override
            public void onComplete() {

            }
        });
    }

    public static void uploadGpsData(final UploadGpsData uploadData,final int TYPE) {
        NetWorkUtil.getInstance().getJstyleApi()
                .uploadGpsData(uploadData).compose(SchedulersTransformer.<NetResultData>io2MainObservable()).subscribe(new Observer<NetResultData>() {
            @Override
            public void onSubscribe(Disposable d) {

            }
            @Override
            public void onNext(NetResultData netResultData) {
                if(0==TYPE){
                    if(netResultData.getMsgCode()==1){
                        UploadGpsDataError error=new UploadGpsDataError();
                        error.setDataTotal(Utils.toJson(uploadData.getDataTotal()));
                        error.setDataType(uploadData.getDataType());
                        error.setMac(uploadData.getMac());
                        error.setUid(uploadData.getUid());
                        StepDetailDataDaoManager.inserGps(error);
                    }
                }else{
                    if(netResultData.getMsgCode()==1){
                        StepDetailDataDaoManager.deleteALLGps();
                    }
                }
            }

            @Override
            public void onError(Throwable e) {
                if(0==TYPE){
                    UploadGpsDataError error=new UploadGpsDataError();
                    error.setDataTotal(uploadData.getDataTotal().toString());
                    error.setDataType(uploadData.getDataType());
                    error.setMac(uploadData.getMac());
                    error.setUid(uploadData.getUid());
                    StepDetailDataDaoManager.inserGps(error);}
            }

            @Override
            public void onComplete() {

            }
        });
    }

    public static UploadData getUploadData(String deviceAddress, String dataType) {
        UploadData uploadData = new UploadData();
        uploadData.setMac(deviceAddress);
        uploadData.setDataType(dataType);
        uploadData.setUid(NetWorkUtil.getUserId());
        return uploadData;
    }

    public static UploadGpsData getUploadGpsData(String deviceAddress) {
        UploadGpsData uploadData = new UploadGpsData();
        uploadData.setMac(deviceAddress);
        uploadData.setDataType(NetWorkConast.gps);
        uploadData.setUid(NetWorkUtil.getUserId());
        return uploadData;
    }

    public static void createDataForRequest(Context context) {
        GoogleSignInAccount googleSignInAccount= GoogleSignIn.getLastSignedInAccount(context);
        if(googleSignInAccount==null)return;
        DataSource dataSourceStep =
                new DataSource.Builder()
                        .setAppPackageName(context)
                        .setDataType(DataType.TYPE_STEP_COUNT_DELTA)
                        .setStreamName("streamName")
                        .setType(DataSource.TYPE_RAW)
                        .build();
        DataSet dataSetStep = DataSet.create(dataSourceStep);
        DataSource dataSourceDistance =
                new DataSource.Builder()
                        .setAppPackageName(context)
                        .setDataType(DataType.TYPE_DISTANCE_DELTA)
                        .setStreamName("streamName")
                        .setType(DataSource.TYPE_RAW)
                        .build();
        DataSet dataSetDistance = DataSet.create(dataSourceDistance);

        DataSource dataSourceCal =
                new DataSource.Builder()
                        .setAppPackageName(context)
                        .setDataType(DataType.TYPE_CALORIES_EXPENDED)
                        .setStreamName("streamName")
                        .setType(DataSource.TYPE_RAW)
                        .build();
        DataSet dataSetCal = DataSet.create(dataSourceCal);
//        List<StepData>stepDataList= StepDataDaoManager.queryAllData();
        List<StepDetailData> stepDetailDataList = StepDetailDataDaoManager.queryAllDataAddress();
        for (StepDetailData stepDetailData : stepDetailDataList) {
            int step = Integer.valueOf(stepDetailData.getStep());
            float distance = Float.valueOf(stepDetailData.getDistance());
            float cal = Float.valueOf(stepDetailData.getCal());
            String time = stepDetailData.getDate();
            // Log.i(TAG, "createStepDataForRequest: "+time+" "+step+" "+distance);
            long startTime = DateUtil.getDefaultLongMi(time);
            Log.i(TAG, "createDataForRequest: "+time);

            if (startTime > System.currentTimeMillis()){
                startTime=System.currentTimeMillis();
            }
            long endTime = startTime + 9 * 60 * 1000l;
            DataPoint dataPoint =
                    dataSetStep.createDataPoint().setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS);
            dataPoint.setIntValues(step > 5400 ? 5400 : step);   //最大值1分钟600步？
            dataSetStep.add(dataPoint);
            DataPoint dataPointDis =
                    dataSetDistance.createDataPoint().setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS);
            dataPointDis.setFloatValues(distance>5000?5:distance / 1000);
            Log.i(TAG, "createDataForRequest: "+distance);
            // Log.i(TAG, "createDataForRequest: "+cal);
            dataSetDistance.add(dataPointDis);

            DataPoint dataPointCal =
                    dataSetCal.createDataPoint().setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS);
            dataPointCal.setFloatValues(cal>300?300:cal);
            //  dataPointCal.setFloatValues(300);
            dataSetCal.add(dataPointCal);
        }
        insetData(dataSetStep, context);
        insetData(dataSetDistance, context);
        insetData(dataSetCal, context);
    }

    private static void insetData(final DataSet dataSet, Context context) {
        GoogleSignInAccount googleSignInAccount= GoogleSignIn.getLastSignedInAccount(context);
        if(googleSignInAccount==null||dataSet.isEmpty())return;

        Fitness.getHistoryClient(context, googleSignInAccount).insertData(dataSet).addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                Log.i(TAG, "onComplete: "+dataSet.getDataType());
                if(!task.isSuccessful()){
                    Log.i(TAG, "onComplete fail: "+dataSet.getDataType()+" "+task.getException());
                }
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.i(TAG, "onFailure: "+dataSet.getDataType()+" "+e.getMessage());
            }
        }).addOnCanceledListener(new OnCanceledListener() {
            @Override
            public void onCanceled() {
                Log.i(TAG, "onCanceled: ");
            }
        });
    }

    public static void createHeartDataForRequest(Context context) {
        DataSource dataSourceHr =
                new DataSource.Builder()
                        .setAppPackageName(context)
                        .setDataType(DataType.TYPE_HEART_RATE_BPM)
                        .setStreamName("streamName")
                        .setType(DataSource.TYPE_RAW)
                        .build();
        DataSet dataSetHr = DataSet.create(dataSourceHr);
        List<HeartData> heartDataList = HeartDataDaoManager.queryAllDataByAddress();
        for (HeartData heartData : heartDataList) {
            int hr = heartData.getHeart();
            String time = heartData.getTime();
            // Log.i(TAG, "createHeartDataForRequest: "+time);
            long startTime = DateUtil.getDefaultLongMi(time);
            long endTime = startTime +  60 * 1000l;
            DataPoint dataPoint =
                    dataSetHr.createDataPoint().setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS);
            dataPoint.getValue(Field.FIELD_BPM).setFloat(hr);
            dataSetHr.add(dataPoint);
        }
        insetData(dataSetHr, context);
    }
}
